<template>
  <view class="base_content" :style="{ height: curHeight }">
    <scroll-view
      :scroll-y="true"
      :scroll-top="scrollTop"
      :scroll-with-animation="true"
      class="scroll-v"
      ref="scrollRef"
    >
      <view class="scroll-content">
        <BaseServiceBox
          v-for="(item, index) in msgDataList"
          :key="index"
          :imgUrl="item.imgUrl"
          :name="item.name"
          :text="item.msg"
          :default-questions="defaultQuestions"
          isMb
          :is-user="item.role !== 'service'"
          :show-ques-cor-tips="item.role === 'service'"
          :show-ques-resolve-tips="
            item.role === 'service' && item.showQuesResTips
          "
          @tipsClicked="quesTipClicked"
        />
      </view>
    </scroll-view>
    <view class="service_act">
      <!--      <view class="btn_box">-->
      <!--        <view class="service_btn">转人工客服</view>-->
      <!--        <view class="service_btn">转电话客服</view>-->
      <!--      </view>-->
      <view class="service_input">
        <input
          v-model="userQuestion"
          :disabled="!isQuesAnswered"
          :cursorSpacing="20"
          placeholder="请输入文字消息"
          inputmode="none"
        />
        <view class="service_sent_btn" @click="sendMyQuestion">
          <view v-if="isQuesAnswered">发送</view>
          <view v-else>
            <view class="loader"></view>
          </view>
        </view>
      </view>
    </view>
    
    <!-- 登录弹窗 -->
    <loginDialog
      @on-off="headelOff"
      @on-make="headelMake"
      :indicate="userLoginDialog"
    >
    </loginDialog>
  </view>
</template>

<script setup>
import loginDialog from "@/components/login/index.vue";
import baseURL from "@/utils/request.js";
import { getCurrentInstance, nextTick, onMounted, ref } from "vue";
import BaseServiceBox from "./component/BaseServiceBox.vue";
import {
  chatToGptApi,
  getConversationContentApi,
  getConversationListAPi,
  getDefaultQuestionAPi,
  joinGtpQueueApi,
} from "@/api/custom-service";
import { atob } from "@/base64/base64.js";
import { px2Rpx, rpx2px } from "../../../utils/utils";
import { onLoad } from "@dcloudio/uni-app";

const { proxy } = getCurrentInstance();
const userLoginInfo = ref("");
const userLoginDialog = ref(false);
// 滚动条位置
const scrollTop = ref(0);

// 滚动试图高度
const scrollViewHeight = ref(0);
const curHeight = ref("100%");

// gpt排队数据
const gptQueueData = ref({});

// 消息数据列表
const msgDataList = ref([
  {
    imgUrl:
      "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
    name: "荣耀小新",
    msg: "你好，我是荣耀殿堂的智能客服，很高兴为你服务。",
    role: "service",
  },
]);
const defaultUserAvatar =
  "https://minio.gzryzl.com/huatai/2024-08-21/1724223934287微信图片_20240821150502.png";

// 用户问题输入框数据
const userQuestion = ref("");
const isQuesAnswered = ref(true);
const currentQues = ref("");
const newConversationId = ref("");

/**
 * scroll-view滚动到底部
 * @returns {Promise<void>}
 */
const scrollToBottom = async () => {
  await nextTick(() => {
    uni
      .createSelectorQuery()
      .in(proxy)
      .select(".scroll-content")
      .boundingClientRect((res) => {
        let top = res.height - scrollViewHeight.value;
        if (top > 0) {
          scrollTop.value = top;
        }
      })
      .exec();
  });
};

/**
 * 获取gpt排队信息
 * @returns {Promise<void>}
 */
const joinGptQueue = async () => {
  const params = {
    gptCode: 1,
  };
  const res = await joinGtpQueueApi(params.gptCode);
  const { code, data } = res;
  if (code === 200) {
    gptQueueData.value = data;
    console.log("排队", data);
  } else {
    console.warn("排队warn", data);
  }
};

/**
 * 获取会话列表
 * @returns {Promise<void>}
 */
const getConversationList = async () => {
  const params = {
    conversationId: "",
    limit: 10,
  };
  const res = await getConversationListAPi(params);
  const { code, data } = res;
  if (code === 200) {
    Array.isArray(data) && (await getConversationContent(data[0]));
  }
};

/**
 * 获取历史对话内容
 * @param conversationData
 * @returns {Promise<void>}
 */
const getConversationContent = async (conversationData) => {
  const { conversationId } = conversationData || {};
  // if (conversationId !== undefined && conversationId !== null) {
  //   newConversationId.value = conversationId;
  // } else {
  //   newConversationId.value = "";
  // }
  const params = {
    conversationId: newConversationId.value,
    limit: 10,
  };
  const res = await getConversationContentApi(params);
  const { code, data } = res;
  if (code === 200) {
    if (Array.isArray(data) && data.length > 0) {
      data.forEach((item) => {
        // 利用query创建用户消息
        msgDataList.value.push({
          imgUrl: uni.getStorageSync("avatar") || defaultUserAvatar,
          name: "我",
          msg: item.query,
          role: "user",
        });

        // 利用answer创建荣耀小新消息
        msgDataList.value.push({
          imgUrl:
            "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
          name: "荣耀小新",
          msg: item.answer,
          role: "service",
          showQuesResTips: true,
          conversationId: item.conversationId,
        });
      });
      await scrollToBottom();
    } else {
      // msgDataList.value.push({
      //   imgUrl:
      //     "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
      //   name: "荣耀小新",
      //   msg: "你好，我是荣耀殿堂的智能客服，很高兴为你服务。",
      //   role: "service",
      // });
      await scrollToBottom();
    }
  }
};

/**
 * 客服提示点击事件
 * @param tips
 */
const quesTipClicked = (tips) => {
  copyText(tips);
  // if (tips.length > 0) {
  //   userQuestion.value = tips;
  // }
};
function copyText(text) {
  uni.setClipboardData({
    data: text,
    success: function () {
      console.log("复制成功");
      // 可以添加用户友好的提示，例如使用uni.showToast提示复制成功
      uni.showToast({
        title: "复制成功",
        icon: "success",
        duration: 2000,
      });
    },
    fail: function () {
      console.log("复制失败");
      // 可以添加错误处理或用户友好的提示
    },
  });
}
function headelOff () {
  userLoginDialog.value = false;
  userQuestion.value = "";
}
function headelMake () {
  userLoginDialog.value = false;
  userLoginInfo.value = uni.getStorageSync("token");
}
/**
 * 监听消息发送按钮
 */
const sendMyQuestion = () => {
  userLoginInfo.value = uni.getStorageSync("token");
  if (!userLoginInfo.value) {
    userLoginDialog.value = true;
  } else {
    if (userQuestion.value.length > 0 && isQuesAnswered.value) {
      isQuesAnswered.value = false;
      currentQues.value = userQuestion.value;
      userQuestion.value = "";
      msgDataList.value.push({
        imgUrl: uni.getStorageSync("avatar") || defaultUserAvatar,
        name: "我",
        msg: currentQues.value,
        role: "user",
      });
      scrollToBottom();
      chatToService();
    }
  }
};

/**
 * 向gpt发起对话
 * @returns {Promise<void>}
 */
const chatToService = async () => {
  let conversationId;
  const serviceMsgList = msgDataList.value.filter(
    (msgData) => msgData.role === "service"
  );
  conversationId =
    serviceMsgList.findLast((msg) => msg.conversationId !== "")
      ?.conversationId || "";
  const params = {
    gptCode: 1,
    conversationId: newConversationId.value,
    query: currentQues.value,
  };
  try {
    const token = uni.getStorageSync("token");

    let xiaoxi = "";
    let max = msgDataList.value.length;
    //  #ifdef MP-WEIXIN
    console.log("max", max);
    const requestTaskWX = uni.request({
      url: `${baseURL}/ht-nonrealtime-gameservice/htgpt/chatToGpt/${params.gptCode}`,
      method: "POST",
      enableChunked: true,
      data: {
        query: currentQues.value,
        conversationId: newConversationId.value,
      },
      header: {
        Authorization: "bearer " + token,
      },
      timeout: 30000,
      success: (response) => {},
      fail: (error) => {
        console.log(error);
      },
    });
    requestTaskWX.onChunkReceived(async function (response) {
      const arrayBuffer = response.data;
      const uint8Array = new Uint8Array(arrayBuffer);
      console.log("原生编码", uint8Array);
      let text = uni.arrayBufferToBase64(uint8Array);
      function base64ToString(base64) {
        return decodeURIComponent(escape(atob(base64)));
      }

      text = base64ToString(text);
      let muban = text.replace(/data:/g, "");
      let lineFeed = muban
        .replace(/[\n\r]+/g, "")
        .replace(/data:/g, "")
        .replaceAll("\\n", "")
        .replace(/"/g, "");
      xiaoxi += lineFeed;
      function containsChar(str, charToFind) {
        return str.includes(charToFind);
      }
      console.log("文字拼接", xiaoxi);
      console.log("判断", containsChar(xiaoxi, ":END"));
      if (containsChar(xiaoxi, ":END")) {
        msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi
          .replace(/:END/g, "")
          .replace(/data:/g, "")
          .replace(/"/g, "");
        console.log("回答结束");
        isQuesAnswered.value = true;
        await scrollToBottom();
      } else {
        if (max == msgDataList.value.length) {
          msgDataList.value.push({
            imgUrl:
              "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
            name: "荣耀小新",
            msg: xiaoxi
              .replace(/data:/g, "")
              .replace(/:END/g, "")
              .replace(/"/g, ""),
            role: "service",
            showQuesResTips: true,
            conversationId: newConversationId.value,
          });
        } else {
          msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi
            .replace(/data:/g, "")
            .replace(/"/g, "");
        }

        await scrollToBottom();
      }
    });
    // #endif
    // #ifdef H5 || APP-PLUS
    let response = await fetch(
      `${baseURL}/ht-nonrealtime-gameservice/htgpt/chatToGpt/${params.gptCode}`,
      {
        method: "post",
        timeout: 60000,
        enableChunked: true,
        body: JSON.stringify({
          query: currentQues.value,
          conversationId: newConversationId.value,
        }),
        headers: {
          "Content-Type": "application/json",
          Authorization: "bearer " + token,
        },
      }
    );
    // console.log("response", response);
    let reader = response.body.getReader();
    while (true) {
      const { done, value } = await reader.read();
      // console.log(done);
      if (done) {
        (msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi
          .replace(/data:/g, "")
          .replace(":END", "")).replace(/"/g, ""),
          (isQuesAnswered.value = true);
        await scrollToBottom();
        // 处理value中的数据
        break;
      }

      // console.log("value", value);
      const arrayBuffer = value;
      const uint8Array = new Uint8Array(arrayBuffer);
      // console.log("原生编码", uint8Array);
      let text = uni.arrayBufferToBase64(uint8Array);
      function base64ToString(base64) {
        return decodeURIComponent(escape(atob(base64)));
      }

      text = base64ToString(text);
      let muban = text.replace(/data:/g, "").replace(/"/g, "");
      let lineFeed = muban
        .replace(/[\n\r]+/g, "")
        .replace(/data:/g, "")
        .replace(/"/g, "");
      xiaoxi += lineFeed;
      // console.log(xiaoxi);
      if (max == msgDataList.value.length) {
        msgDataList.value.push({
          imgUrl:
            "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
          name: "荣耀小新",
          msg: xiaoxi
            .replace(/data:/g, "")
            .replace(":END", "")
            .replace(/"/g, ""),
          role: "service",
          showQuesResTips: true,
          conversationId: newConversationId.value,
        });
      } else {
        msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi.replace(
          "data:",
          ""
        );
      }
      await scrollToBottom();
    }
    // const requestTask = wx.request({
    //   url: `${baseURL}/ht-nonrealtime-gameservice/htgpt/chatToGpt/${params.gptCode}`,
    //   method: "POST",
    //   enableChunked: true,
    //   // responseType: 'stream', // 设置响应类型为流数据
    //   data: {
    //     query: currentQues.value,
    //     conversationId: newConversationId.value,
    //   },
    //   header: {
    //     Authorization: "bearer " + token,
    //   },
    //   success: (res) => {
    //     console.log(res);
    //     res.data.on("data", function (chunk) {
    //       console.log(chunk); // 处理接收到的数据
    //     });
    //     res.data.on("end", function () {
    //       console.log("数据流接收完毕");
    //     });
    //   },
    //   fail: (error) => {},
    // });
    // console.log("requestTask", requestTask);
    // requestTask.constructor(async function (response) {
    //   console.log("response",response);
    //   // const arrayBuffer = response.data;
    //   // const uint8Array = new Uint8Array(arrayBuffer);
    //   // let text = uni.arrayBufferToBase64(uint8Array);
    //   // function base64ToString(base64) {
    //   //   return decodeURIComponent(escape(atob(base64)));
    //   // }
    //   // text = base64ToString(text);
    //   // let muban = text.replace(/data:/g,'');
    //   // let lineFeed = muban.replace(/[\n\r]+/g, "");
    //   // xiaoxi += lineFeed;
    //   // function containsChar(str, charToFind) {
    //   //   return str.includes(charToFind);
    //   // }
    //   // if (containsChar(xiaoxi, ":END")) {
    //   //   msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi
    //   //     .replace(":END", "")
    //   //     .replace(/data:/g,'');
    //   //   isQuesAnswered.value = true;
    //   //   await scrollToBottom();
    //   // } else {
    //   //   if (max == msgDataList.value.length) {
    //   //     msgDataList.value.push({
    //   //       imgUrl:
    //   //         "https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png",
    //   //       name: "荣耀小新",
    //   //       msg: xiaoxi.replace(/data:/g,''),
    //   //       role: "service",
    //   //       showQuesResTips: true,
    //   //       conversationId,
    //   //     });
    //   //   } else {
    //   //     msgDataList.value[msgDataList.value.length - 1].msg = xiaoxi.replace(
    //   //       "data:",
    //   //       ""
    //   //     );
    //   //   }
    //   // }
    //   // await scrollToBottom();
    // });
    // #endif
    // const res = await chatToGptApi(params)
    // const {code, data} = res
    // if (code === 200) {
    //   const {answer, conversationId} = data || {}
    //   msgDataList.value.push({
    //     imgUrl: 'https://minio.gzryzl.com/huatai/2024-04-07/1712478087613rongyao.png',
    //     name: '荣耀小新',
    //     msg: answer,
    //     role: 'service',
    //     showQuesResTips: true,
    //     conversationId
    //   })
    //   isQuesAnswered.value = true
    //   await scrollToBottom()
    // } else if (code === 400) {
    //   await uni.showToast({
    //     title: res.msg,
    //     icon: 'error',
    //     duration: 5000,
    //   })
    //   isQuesAnswered.value = true
    //   userQuestion.value = currentQues.value
    //   await joinGptQueue()
    //   // await chatToService()
    // }
  } catch (e) {
    console.error(e);
    isQuesAnswered.value = true;
  }
};

const getScrollViewHeight = () => {
  // 获取视窗高度
  const windowHeight =
    window.innerHeight ||
    document.documentElement.clientHeight ||
    document.body.clientHeight;

  // 计算高度
  scrollViewHeight.value = windowHeight * 0.8 - 50;
};

const defaultQuestions = ref([[]]);
const getDefaultQuestion = async () => {
  const res = await getDefaultQuestionAPi();
  const { code, data } = res;
  if (code === 200) {
    console.log(data);
    defaultQuestions.value = data.map((item) => item.question);
  }
};

onMounted(() => {
  joinGptQueue();
  getConversationList();
  getScrollViewHeight();
  getDefaultQuestion();
});
</script>
<style lang="less" scoped>
/* #ifdef MP-WEIXIN*/
.base_content {
  height: 100vh;
  /* #ifdef MP-WEIXIN */
  padding-bottom: calc(constant(safe-area-inset-bottom));
  padding-bottom: calc(env(safe-area-inset-bottom));
  /* #endif */
}

/* #endif */
.base_content {
  font-family: "ali", serif;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* #ifdef H5 */
  height: 100%;
  /* #endif */
  width: 100%;

  .scroll-v {
    padding: 30rpx 30rpx 140rpx 30rpx;
    box-sizing: border-box;
    overflow-y: scroll;
    height: calc(99vh - 50rpx);
  }

  .service_act {
    position: fixed;
    bottom: 0;
    /* #ifdef MP-WEIXIN */
    bottom: calc(constant(safe-area-inset-bottom));
    bottom: calc(env(safe-area-inset-bottom));
    /* #endif */
    width: 100vw;

    .btn_box {
      display: flex;
      padding: 0 25rpx;
      box-sizing: border-box;
      margin-bottom: 22rpx;

      .service_btn {
        font-size: 23rpx;
        color: #272636;
        padding: 18rpx 46rpx;
        background-color: #fff;
        border-radius: 13rpx;
        border: 1px solid #dadada;
        box-sizing: border-box;
        margin-right: 33rpx;
      }
    }

    .service_input {
      border-top: 1px solid #dadada;
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 114rpx;
      padding: 0 20rpx 0 54rpx;
      box-sizing: border-box;
      background-color: #fff;

      input {
        flex: 1;
        font-size: 23rpx;
      }

      .service_sent_btn {
        padding: 15rpx 40rpx;
        color: #ffffff;
        box-sizing: border-box;
        background-color: #00b588;
        border-radius: 13rpx;
        margin-left: 20rpx;
      }

      /* 简单的加载动画样式 */

      .loader {
        border: 4px solid #f3f3f3;
        border-radius: 50%;
        border-top: 4px solid #3498db;
        width: 16px;
        height: 16px;
        -webkit-animation: spin 2s linear infinite; /* Safari */
        animation: spin 2s linear infinite;
      }

      /* Safari */
      @-webkit-keyframes spin {
        0% {
          -webkit-transform: rotate(0deg);
        }
        100% {
          -webkit-transform: rotate(360deg);
        }
      }

      @keyframes spin {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(360deg);
        }
      }
    }
  }
}
</style>
